using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RopeCanon : MonoBehaviour
{
	public int					_hookDestructionDistance = 20;
	public Transform			_hookPrefap;
	public const float			FIRE_DELAY = .5f;
	public float				_power = 10.0f;
	public const float			WAIPOINT_INTERVALL = 0.4f; //setting waypoints in this intervall

	private float				_fireTimer = 0.0f;
	private Transform			_currentHook = null;
	private Transform			_currentPlanet;
	private List<Vector3>		_coverDistancePnts = new List<Vector3>();
	private bool				_hasRope = false;
	private float				_passedHookDistance = 0.0f;
	private Character			_character;
	

	// Use this for initialization
	void Start ()
	{
		//getting character info
		_currentPlanet = gameObject.transform.parent.GetComponent<CustomGravity>()._currentPlanet;
		_character = gameObject.transform.parent.GetComponent<Character>();
		gameObject.transform.position = _character.transform.position;
	}
	
	// Update is called once per frame
	void Update()
	{
		_fireTimer += Time.deltaTime;

		//create hook on press fire button
		if ( Input.GetButton( "FireRope" ) && FIRE_DELAY >= 0 && _currentHook == null )
		{
			_currentHook = (Transform)Instantiate( _hookPrefap,
									_character.transform.position,
									_character.transform.rotation );
			
			//setting properties after initialization
			Hook _hook = _currentHook.GetComponent<Hook>();
			_hook._character = _character;
			CustomGravity _hookGravity = _currentHook.GetComponent<CustomGravity>();
			_hookGravity._currentPlanet = _currentPlanet;
	
			//giving direction and power to hook
			Crosshair _crosshair = GameObject.Find( "Crosshair" ).GetComponent<Crosshair>();
			
			_currentHook.rigidbody.AddForce( _crosshair.getShotDirection() * _power, ForceMode.Impulse );
			_fireTimer = 0.0f;

			//-----------DEBUG----------------->
			Vector3 _shotDirec = _crosshair.getShotDirection();
			Debug.Log( "Fire shotdirec x: "
					 + _shotDirec.x + " y: "
					 + _shotDirec.y + " z: "
					 + _shotDirec.z );
			
		}
		//if there is a hook for the ropecanon, check if it is hooked
		else if ( _currentHook != null )
		{
			//recording waypoints 
			Hook _hook = _currentHook.GetComponent<Hook>();
			if ( !_hook._isHooked )
			{
				//adding waypoints for creating a rope later on
				float _distSinceLastUpdt = 0.0f;
				if(_coverDistancePnts.Count > 0 )
					_distSinceLastUpdt = Vector3.Distance(
												_coverDistancePnts[_coverDistancePnts.Count -1 ],
												_currentHook.transform.position);

				if ( _coverDistancePnts.Count == 0 || _distSinceLastUpdt >= .7f )
				{
					_passedHookDistance += _distSinceLastUpdt;
					_coverDistancePnts.Add( _currentHook.transform.position );

					//-----------DEBUG----------------->
					Debug.Log( "add wt-pnt" );
				}
			}
			else if ( !_hasRope )
			{
				// building up a rope from the canon to the hook
				buildRope( _character.gameObject, _currentHook.gameObject );
			}

			//delete hook on REPRESS fire
			//destroy object if rope woulg get too long
			if ( _passedHookDistance >= _hookDestructionDistance || Input.GetButton( "FireRope" ) )
			{
				DestroyObject( _currentHook.gameObject );
				_currentHook = null;
				_hasRope = false;
				_passedHookDistance = 0.0f;
				_coverDistancePnts.Clear();

				Object[] _objects = GameObject.FindObjectsOfType( typeof( RopepartIdentifier ) );

				foreach ( RopepartIdentifier _partId in _objects )
				{
					if ( _partId._partOfChar == _character )
						Destroy( _partId.gameObject );
				}
				//-----------DEBUG----------------->
				Debug.Log( "destroy hook" );
			}
		}
	}

	private void buildRope( GameObject begin, GameObject end )
	{
		_hasRope = true;
		Rigidbody _rigidBef = begin.rigidbody;
		HingeJoint _j = null;
		for ( int i=0; i<_coverDistancePnts.Count; ++i )
		{
			GameObject _o = GameObject.CreatePrimitive( PrimitiveType.Capsule );
			_o.transform.position = _coverDistancePnts[i];
			_o.transform.localScale = new Vector3( .1f, .1f, .1f );

			Rigidbody _rb = _o.AddComponent<Rigidbody>();
			_rb.transform.localScale = new Vector3( .1f, .1f, .1f );

			_j = _o.AddComponent<HingeJoint>();
			_j.connectedBody = _rigidBef;

			CustomGravity _cg = _o.AddComponent<CustomGravity>();
			_cg._currentPlanet = GameObject.Find( "Earth" ).transform;
			_rigidBef = _rb;

			//writing referenc to identifier -> resolving parts for certain players
			RopepartIdentifier _partId = _o.AddComponent<RopepartIdentifier>();
			_partId._partOfChar = _character;

			//connect joint of hook at the end
			if ( i == _coverDistancePnts.Count - 1 )
				end.AddComponent<HingeJoint>().connectedBody = _rigidBef;
		}
		
	}
}
